package com.itheima.tlias.controller;

import com.itheima.tlias.entity.Dept;
import com.itheima.tlias.util.ResultUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 测试ioc与di
 * 使用IOC和DI时,
 * Bean对象的创建和获取都和IOC容器有关
 * Bean对象不能调用非Bean对象
 *
 *DI : 从IOC容器中获取已经创建好的对象给属性(成员变量)赋值
 *
 * 给一个类的属性(成员变量)赋值  有四种方式:
 * 1.直接=赋值
 * 2.构造器
 * 3.set方法
 * 4.反射
 *
 * @Autowired 一般使用在构造器赋值和set方法赋值时
 * 所以说SpringDI注入有三种方式
 * 1.字段(属性)DI -> @Resource
 * 2.构造器DI -> @Autowired
 * 3.set方法DI -> @Autowired
 *
 * @Resource与@Autowired使用:
 * 如果一个SpringBoot类中值需要注入很少的其他Bean对象 -> 优先使用@Resource
 * 如果一个SpringBoot类中值需要注入很多的其他Bean对象 -> 优先使用@Autowired
 *
 *
 * SpringBean注入时要注意的问题 :
 * 1.非Bean不能调用Bean
 * 2.不能形成循环依赖 -> 如何解决?
 */
@Slf4j
@RestController
@RequestMapping("ioc_di")
public class TestIOCAndDIController {

    /**
     * 属性注入优先使用@Resource
     * 默认按照Bean名称从容器中获取 -> 默认的SpringBean名字是类对应的小驼峰
     * 不同包下有可能存在同名类 -> 解决办法 :  @Component注解在创建Bean时指定名字  同时@Resource从ioc容器中获取时也指定名字
     */
    @Resource
    Dept dept;

    @GetMapping("/dept")
    public ResultUtil createDeptByIoc(){
        //使用springboot ioc 自动创建一个Dept对象
        log.info("自动创建的dept对象{}",dept);
        return ResultUtil.success(dept);
    }
}
